#ifndef __NETWORKFILEMANAGER_H__
#define __NETWORKFILEMANAGER_H__

//#include "NetworkMusicFile.h"
//#include "NetworkLyricFile.h"

namespace SPlayer
{
    namespace Network
    {
        using namespace System;
        using namespace System::Net;
        using namespace System::Net::Sockets;
        using namespace System::Collections::Concurrent;
        using namespace System::Collections::Generic;
        using namespace SPlayer;
        using namespace System::IO;

        template <class NetworkFile>
        ref class NetworkFileManager;
        ref class NetworkMusicFile;
        ref class NetworkLyricFile;

        ref class NetworkFileManagerEventDispatcher
        {
        public:
            Action<String ^/*musicTitle*/, array<unsigned char> ^/*filedata*/> ^onFileDownloaded;
        };

        template <class NetworkFile>
        ref class NetworkFileManager
        {
        public:
            NetworkFile ^getFile(String ^musicTitle)
            {
                if (!hasFile(musicTitle))
                {
                    auto file = gcnew NetworkFile(musicTitle);
                    musicFiles->TryAdd(musicTitle, file);

                    auto myOnMusicFileDownloadFinished = gcnew Action<NetworkFile ^>(this, &NetworkFileManager<NetworkFile>::onMusicFileDownloadFinished);

                    file->eventDispatcher->onDownloadFinished += Common::Function::bindFirst(myOnMusicFileDownloadFinished, file);
                    return file;
                }
                
                return musicFiles[musicTitle];
            }
        public:
            bool hasFile(String ^musicTitle)
            {
                return musicFiles->ContainsKey(musicTitle);
            }
        public:
            void onMusicFileDownloadFinished(NetworkFile ^file)
            {
                Common::Function::InvokeSync(eventDispatcher->onFileDownloaded, file->musicTitle, file->filedata);
            }
        public:
            ConcurrentDictionary<String ^/*musicTitle*/, NetworkFile ^/*fileinstance*/> ^musicFiles = gcnew ConcurrentDictionary < String ^/*filename*/, NetworkFile ^/*fileinstance*/ >;
            NetworkFileManagerEventDispatcher ^eventDispatcher = gcnew NetworkFileManagerEventDispatcher;
        public:
            static NetworkFileManager<NetworkFile> ^globalManager = gcnew NetworkFileManager<NetworkFile>;
        };
    }
}

#endif // __NETWORKFILEMANAGER_H__